home *** CD-ROM | disk | FTP | other *** search
- TITLE MSDOS2 PATHNAME PARSER
-
- PATHSIZE EQU 65
- .XLIST
- INCLUDE MSDOS2.DEF
- .LIST
-
- CODE SEGMENT BYTE PUBLIC
- ASSUME CS:CODE
- EXTRN CPYCNT:NEAR
- PUBLIC TYPE_UFN,TYPE_AFN,TYPE_DIR
- PUBLIC TYPE_DSP,TYPE_DRV,TYPE_UNK
- PUBLIC FIXPATH
-
- ; THIS PROCEDURE PARSES A (POSSIBLY AMBIGUOUS) DOS PATH NAME
- ; INTO A SEARCH PATH AND A LEAD-IN PATH. THE SEARCH PATH CAN
- ; BE USED AS AN ARGUMENT TO DOS FUNCTIONS 4E AND 4F. THE
- ; LEAD-IN PATH IS INTENDED TO BE PREFIXED TO THE SIMPLE FILENAME
- ; RETURNED BY THESE FUNCTIONS, IN ORDER TO PRODUCE A COMPLETE
- ; PATH NAME USABLE BY OPEN, RENAME, ETC.
- ;
- ; DS = ES IS ASSUMED.
- ;
- ; MODELLED AFTER THE C FUNCTION fixpath() IN DR. DOBB'S JOURNAL,
- ; OCT. 1985, PP. 16-18.
- ;
- ; ENTRY: BX - POINTS TO INPUT PATH
- ; CX - POINTS TO SEARCH PATH
- ; DX - POINTS TO LEAD-IN PATH
- ; EXIT:
- ; AX = 0 IF PATH IS AN UNAMBIGUOUS FILE NAME
- ; = 1 IF PATH IS AN AMBIGUOUS FILE NAME (E.G. "FOO?.*")
- ; = 2 IF PATH IS A DIRECTORY SPEC (E.G.: A:\FOO\BAR\")
- ; = 3 IF PATH IS A DRIVE SPEC (E.G. "A:") OR NULL STRING
- ; = 4 IF PATH IS A DIRECTORY
- ; = 5 IF PATH TYPE UNKNOWN OR DOES NOT EXIST
- ;
- ; USES: SI,DI,FLAGS
- ;
- TYPE_UFN EQU 0
- TYPE_AFN EQU 1
- TYPE_DRV EQU 2
- TYPE_DSP EQU 3
- TYPE_DIR EQU 4
- TYPE_UNK EQU 5
-
- COPYPATH MACRO
- PUSH CX
- MOV CX,PATHSIZE
- CALL CPYCNT
- POP CX
- ENDM
-
- COPYDATA MACRO
- PUSH DS
- MOV AX,CODE
- MOV DS,AX
- COPYPATH
- POP DS
- ENDM
-
- SSTARS: DB '\'
- STARS: DB '*.*',0
- SLASHALONE: DB '\',0
-
- FIXPATH PROC NEAR
- CMP BYTE PTR [BX],0
- JE DRVSPEC ;IF NULL STRING
- CMP BYTE PTR [BX+1],':' ;CHECK FOR DRIVE SPEC
- JNE NODSPEC ;IF NONE
- CMP BYTE PTR [BX+2],0 ;CHECK FOR ONLY DRIVE SPEC
- JE DRVSPEC ;IF THAT'S WHAT IT IS
- NODSPEC:
- MOV DI,BX
- PUSH CX
- MOV CX,80
- MOV AL,0
- REPNE SCASB ;FIND END OF STRING
- POP CX
- DEC DI
- DEC DI
- MOV AL,[DI] ;GET LAST CHAR.
- CMP AL,'.' ;IS IT DOT?
- JE DOT ;YES.
- CMP AL,'\' ;IS IT BACKSLASH?
- JNE FIXPATH2 ;NO.
- MOV AX,TYPE_DSP
- JMP SHORT DIRSPEC ;YES, IT IS, ASSUME (*.*)
- DOT: DEC DI ;LAST CHAR. DOT
- CMP BYTE PTR [DI],'.' ;IS PREV. CHAR. DOT, TOO?
- JE DOTDOT ;.., SEE IF IT EXISTS
- MOV BYTE PTR [DI+1],0 ;ONE DOT AT END OF PATH, ERASE IT
- MOV AX,TYPE_DSP
- JMP SHORT DIRSPEC ;TREAT AS DIRECTORY SPEC
- DRVSPEC:
- MOV AX,TYPE_DRV
- DIRSPEC:
- PUSH AX ;SAVE PATH TYPE
- MOV SI,BX
- MOV DI,DX
- COPYPATH ;COPY INPUT TO LEAD-IN PATH
- MOV SI,BX
- MOV DI,CX
- COPYPATH ;COPY INPUT TO SEARCH PATH
- DEC DI ;BACK UP OVER NULL
- MOV SI,OFFSET CODE:STARS
- COPYDATA ;NOW ADD "*.*" TO SEARCH PATH
- POP AX ;RETURN PATH TYPE
- RET
- DOTDOT: INC DI
- FIXPATH2:
- PUSH CX
- PUSH DX
- MOV DX,BX
- MOV CX,0
- MOV AH,CHMOD
- MOV AL,0
- INT DOS ;GET ATTRIBUTES FROM PATH
- POP DX
- JC BADNAME ;IF ERROR
- TEST CX,0010H ;IS IT A DIRECTORY?
- POP CX
- MOV AX,TYPE_UFN ;SIGNAL UFN, JUST IN CASE
- JZ FIXPATH3 ;IF NOT DIRECTORY, IS UFN
- JMP SHORT FIXPATH4 ;IF DIRECTORY
- BADNAME:
- POP CX
- CMP AX,3 ;IF ERROR CODE 3,
- JZ TESTWILD ;MIGHT BE VALID (BUT AMBIGUOUS) PATH NAME
- MOV AX,TYPE_UNK ;SET TYPE =UNKNOWN
- JMP SHORT FIXPATH3 ;WEIRD ERROR CODE, TREAT PATH AS A UFN
- TESTWILD: ;CAN'T GET ATTRIBUTES, SEE IF
- PUSH BX ;PATH INCLUDES WILDCARDS
- WLOOP: MOV AL,[BX]
- CMP AL,0
- JE NOTWILD
- CMP AL,'*'
- JE WILD
- CMP AL,'?'
- JE WILD
- INC BX
- JMP WLOOP
- WILD: POP BX ;FOUND WILD CARD,
- MOV AX,TYPE_AFN ;SET PATH TYPE = AFN
- JMP SHORT FIXPATH3
- NOTWILD:
- POP BX ;NO WILD CARD FOUND,
- MOV AX,TYPE_UNK ;SET PATH TYPE UNKNOWN
- FIXPATH3: ;COME HERE IF PATH IS AFN, UFN OR UNKNOWN
- PUSH AX
- PUSH DX
- PUSH BX
- MOV SI,BX
- MOV DI,CX
- PUSH CX
- COPYPATH ;MAKE SEARCH PATH=INPUT PATH
- POP DX ;DX = START OF PATH
- MOV BX,DI ;BX = END OF PATH (1 PAST NULL)
- DEC BX
- SRCLUP: CMP BX,DX ;AT START OF PATH?
- JLE ENDSRC ;YUP.
- MOV AL,[BX] ;GET A CHAR. FROM PATH
- CMP AL,'\' ;IS IT BACKSLASH OR COLON?
- JE RETAIN
- CMP AL,':'
- JE RETAIN
- DEC BX ;NO, BACK UP 1
- JMP SRCLUP ;KEEP SEARCHING
- RETAIN: INC BX
- ENDSRC: MOV [BX],BYTE PTR 0 ;ZAP WHATEVER IS AFTER ':' OR '\'
- POP BX
- POP DX
- MOV SI,CX
- MOV DI,DX
- COPYPATH ;COPY SEARCH PATH TO LEAD-IN PATH
- MOV SI,BX
- MOV DI,CX
- COPYPATH ;WHOLE INPUT FOR SEARCH
- POP AX ;RESTORE TYPE
- RET
- FIXPATH4: ;COME HERE IF PATH IS A DIRECTORY
- MOV SI,BX
- MOV DI,CX
- COPYPATH ;COPY INPUT TO SEARCH PATH
- DEC DI ;BACK UP OVER NULL
- MOV SI,OFFSET CODE:SSTARS ;POINT TO "\*.*"
- COPYDATA ;ADD TO SEARCH PATH
- MOV SI,BX
- MOV DI,DX
- COPYPATH ;COPY INPUT TO LEAD-IN PATH
- DEC DI ;BACK UP OVER NULL
- MOV SI,OFFSET CODE:SLASHALONE ;POINT TO "\"
- COPYDATA ;ADD TO LEAD-IN PATH
- MOV AX,TYPE_DIR ;SIGNAL DIRECTORY
- RET
- FIXPATH ENDP
- CODE ENDS
- END